package com.xj.nrpc.client;

import java.util.List;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.CuratorWatcher;

import com.alibaba.fastjson.JSONObject;
import com.xj.nrpc.client.future.DefaultFuture;
import com.xj.nrpc.client.handler.ClientHandler;
import com.xj.nrpc.client.manager.ChannelManager;
import com.xj.nrpc.client.manager.ServerWatcher;
import com.xj.nrpc.core.constant.Constants;
import com.xj.nrpc.core.util.RequestEntity;
import com.xj.nrpc.core.util.ResponseEntity;
import com.xj.nrpc.zk.ZookeeperFactory;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class TCPClient {

	public static final Bootstrap bootstrap = new Bootstrap();
	static {


		try {
			EventLoopGroup group = new NioEventLoopGroup();
			bootstrap.group(group);
			bootstrap.channel(NioSocketChannel.class);
			bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
			
			bootstrap.handler(new ChannelInitializer<SocketChannel>() {
				protected void initChannel(SocketChannel ch) throws Exception {
					ch.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]));
					ch.pipeline().addLast(new StringDecoder());
					ch.pipeline().addLast(new ClientHandler());
					ch.pipeline().addLast(new StringEncoder());
				};
			});
			
			CuratorWatcher watcher = new ServerWatcher();
			CuratorFramework cf = ZookeeperFactory.create();
			cf.getChildren().usingWatcher(watcher).forPath(Constants.SERVER_PATH);
			
			//获取到所有的服务列表
			List<String> list = cf.getChildren().forPath(Constants.SERVER_PATH);
			
			for(String path : list){
				String[] ps = path.split("#");
				String ip = ps[0];
				Integer port = new Integer(ps[1]);
				Integer weight = new Integer(ps[2])>10?10:new Integer(ps[2]);
				if(weight > 0){
					for(int i=0;i<weight;i++){
						ChannelManager.realPathsAdd(ip+"#"+port);
						ChannelFuture f = bootstrap.connect(ip,port).sync();
						ChannelManager.channelFuturesAdd(f);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static ResponseEntity send(RequestEntity request) {
		ChannelFuture channelFuturesGet = ChannelManager.channelFuturesGet(ChannelManager.index);
		channelFuturesGet.channel().writeAndFlush(JSONObject.toJSONString(request));
		channelFuturesGet.channel().writeAndFlush("\r\n");
		DefaultFuture df = new DefaultFuture(request);

		return df.get();
	}

}
